#include <stdio.h>
#include <string.h>
#include <stdlib.h>

#include "spi.h"


#define SPI_CLK_GPIO_CLK    RCC_APB2Periph_GPIOG
#define SPI_CLK_GPIO_PORT   GPIOG
#define SPI_CLK_CPIO_PIN    GPIO_Pin_7

#define SPI_MOSI_GPIO_CLK   RCC_APB2Periph_GPIOF
#define SPI_MOSI_GPIO_PORT  GPIOF
#define SPI_MOSI_GPIO_PIN   GPIO_Pin_11

#define SPI_MISO_GPIO_CLK   RCC_APB2Periph_GPIOF
#define SPI_MISO_GPIO_PORT  GPIOF
#define SPI_MISO_GPIO_PIN   GPIO_Pin_6


#ifdef SOFT_SPI

#define SPI_CLK_0()     GPIO_ResetBits(SPI_CLK_GPIO_PORT, SPI_CLK_CPIO_PIN)
#define SPI_CLK_1()     GPIO_SetBits(SPI_MOSI_GPIO_PORT, SPI_CLK_CPIO_PIN)

#define SPI_MOSI_0()    GPIO_ResetBits(SPI_CLK_GPIO_PORT, SPI_MOSI_GPIO_PIN)
#define SPI_MOSI_1()    GPIO_SetBits(SPI_CLK_GPIO_PORT, SPI_MOSI_GPIO_PIN)     

#define SPI_MISO()      (GPIO_ReadInputDataBit(SPI_MISO_GPIO_PORT, SPI_MISO_GPIO_PIN)==Bit_SET)

#endif

uint8_t g_spi_busy = 0;

void spi_init(void) 
{
#ifdef SOFT_SPI
    RCC_APB2PeriphClockCmd(SPI_CLK_GPIO_CLK|SPI_MOSI_GPIO_CLK|SPI_MISO_GPIO_CLK, ENABLE);

    gpio_conf(SPI_CLK_GPIO_PORT, SPI_CLK_CPIO_PIN, GPIO_Mode_Out_PP, GPIO_Speed_10MHz);
    gpio_conf(SPI_MOSI_GPIO_PORT, SPI_MOSI_GPIO_PIN, GPIO_Mode_Out_PP, GPIO_Speed_10MHz);
    gpio_conf(SPI_MISO_GPIO_PORT, SPI_MISO_GPIO_PIN, GPIO_Mode_IPU, GPIO_Speed_10MHz);
    
#endif
}


#ifdef SOFT_SPI

void spi_delay(void) 
{
    uint32_t i;

    for(i=0; i<2; i++);
}

#endif

/*********************************************************************************************
** Function name:           spi_write
** Descriptions:            向SPI总线发送一个字节，CLK上升沿采集数据，CLK空闲时为低电平
** input parameters:        ucByte：写入的数据
** output parameters:       
** Returned value:          SMAG_SUCCESS: 成功
** Created by:              zheh.zhang
** Created date:            2021-09-03
**--------------------------------------------------------------------------------------------
** Modified by:
** Modified date:
**********************************************************************************************/
void spi_write(uint8_t ucByte)
{
#ifdef SOFT_SPI
    uint8_t i;

    SPI_MOSI_0();
    SPI_CLK_0();

    for(i=0; i<8; i++) {
        if(ucByte & 0x80) {
            SPI_MOSI_1();
        } else {
            SPI_MOSI_0();
        }

        spi_delay();
        SPI_CLK_1();

        ucByte <<= 1; 

        spi_delay();
        SPI_CLK_0();
        
    }
#endif
}

/*********************************************************************************************
** Function name:           spi_read
** Descriptions:            从SPI总线接收一个字节，CLK上升沿采集数据，CLK空闲时为低电平
** input parameters:        none
** output parameters:       
** Returned value:          返回获取的数据
** Created by:              zheh.zhang
** Created date:            2021-09-03
**--------------------------------------------------------------------------------------------
** Modified by:
** Modified date:
**********************************************************************************************/
uint8_t spi_read(void)
{
    uint8_t i;
    uint8_t read = 0;

    SPI_MOSI_0();
    SPI_CLK_0();

    for(i=0; i<8; i++) {
        read <<= 1;
        if(SPI_MISO()) {
            read++;
        }
        spi_delay();
        SPI_CLK_1();

        spi_delay();
        SPI_CLK_0();
    }

    return read;
}

void spi_busy_enter(void)
{
    g_spi_busy = 1;
}

void spi_busy_exit(void)
{
    g_spi_busy = 0;
}

uint8_t spi_busy_check(void)
{
    return g_spi_busy;
}

